package com.wash.shoes.task;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.utils.StringUtils;
import com.wash.shoes.domain.dy.model.DyBookNotifyCallBackVo;
import com.wash.shoes.domain.dy.request.DyBookRequest;
import com.wash.shoes.entity.OrderGoodPo;
import com.wash.shoes.entity.OrderPo;
import com.wash.shoes.mapper.OrderGoodMapper;
import com.wash.shoes.mapper.OrderMapper;
import com.wash.shoes.queue.RedisDelayQueue;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RQueue;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 抖音接单结果回调
 */
@RequiredArgsConstructor
@Component
@Slf4j(topic = "DY_BOOKCALLBACK")
public class DyBookResultCallbackWorker extends Thread {

    /**
     * 抖音接单结果回调
     */
    private final RedissonClient redissonClient;

    private final DyBookRequest dyBookRequest;

    private final OrderMapper orderMapper;

    private final OrderGoodMapper orderGoodMapper;

    @PostConstruct
    public void init() {
        start();
        log.info("DyBookResultCallbackWorker init");
    }

    public void run() {
        log.info("DyBookResultCallbackWorker start");

        try {
            RQueue<String> queue = redissonClient.getQueue(RedisDelayQueue.BOOKING_RESULT_CALLBACK_QUEUE);
            while (true) {
                String dyBookNotifyCallBackVoStr = queue.poll();
                //判断取到的订单号是否为空,为空则休眠1秒
                if (StringUtils.isNotEmpty(dyBookNotifyCallBackVoStr)) {
                    DyBookNotifyCallBackVo dyBookNotifyCallBackVo = null;
                    try {
                        dyBookNotifyCallBackVo = JSONUtil.toBean(dyBookNotifyCallBackVoStr, DyBookNotifyCallBackVo.class);
                    } catch (Exception e) {
                        log.error("DyBookResultCallbackWorker convert DyBookNotifyCallBackVo error,dyBookNotifyCallBackVoStr:" + dyBookNotifyCallBackVoStr, e);
                    }
                    if (Objects.nonNull(dyBookNotifyCallBackVo) && StringUtils.isNotEmpty(dyBookNotifyCallBackVo.getOrderId())) {

                        log.info("DyBookResultCallbackWorker dyBookNotifyCallBackVo:{}", dyBookNotifyCallBackVo);
                        //获取到抖音那条预约的记录
                        OrderGoodPo orderGoodPo = orderGoodMapper.selectOne(new LambdaQueryWrapper<OrderGoodPo>().eq(OrderGoodPo::getItemOrderId, dyBookNotifyCallBackVo.getItemOrderId()));
                        if (Objects.isNull(orderGoodPo)) {
                            log.info("DyBookResultCallbackWorker orderGoodPo is null,itemOrderId:" + dyBookNotifyCallBackVo.getItemOrderId());
                            continue;
                        }
                        OrderPo orderPo = orderMapper.selectById(dyBookNotifyCallBackVo.getOrderId());

                        if (Objects.nonNull(orderPo)) {
                            log.info("DyBookResultCallbackWorker orderPo:{}", orderPo);
                            boolean result = dyBookRequest.bookResultCallback(orderPo, orderGoodPo);
                            log.info("DyBookResultCallbackWorker bookResultCallback.orderId:{}, orderNo:{}  ,result:{}", orderPo.getId(), orderPo.getOrderNo(), result);
                            orderGoodPo.setAccepted(result);
                            orderGoodMapper.updateById(orderGoodPo);
                            long count = orderGoodMapper.selectCount(new LambdaQueryWrapper<OrderGoodPo>().eq(OrderGoodPo::getOrderId, orderPo.getId()));
                            //订单的数量等于已接单的数量
                            if (count == orderGoodMapper.selectCount(new LambdaQueryWrapper<OrderGoodPo>().eq(OrderGoodPo::getOrderId, orderPo.getId()).eq(OrderGoodPo::getAccepted, true))) {
                                //调用预约接单接口
                                log.info("dy book result callback,orderId:{} flag:{},orderNo:{}", orderPo.getId(), result, orderPo.getOrderNo());
                                orderPo.setAccepted(result);
                                orderMapper.updateById(orderPo);
                            }
                            //处理失败，重试3次
                            if (!result && dyBookNotifyCallBackVo.getRetryCount() < 3) {
                                RQueue<String> delayQueue = redissonClient.getQueue(RedisDelayQueue.BOOKING_RESULT_CALLBACK_QUEUE);
                                RDelayedQueue<String> queue1 = redissonClient.getDelayedQueue(delayQueue);
                                dyBookNotifyCallBackVo.addRetryCount();
                                queue1.offer(JSONUtil.toJsonStr(dyBookNotifyCallBackVo), 3, TimeUnit.SECONDS);
                                log.info("DyBookResultCallbackWorker bookResultCallback. orderId:{}  ,record:{} , retryCount:{} , end.", dyBookNotifyCallBackVo.getOrderId(), dyBookNotifyCallBackVo, dyBookNotifyCallBackVo.getRetryCount());
                            }
                        }
                    }

                } else {
                    sleep(TimeUnit.SECONDS.toMillis(1));
                }
            }
        } catch (Exception e) {
            log.error("DyBookResultCallbackWorker error", e);
        }
    }
}
